package misc

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io"
	"math"
	"net/url"
	"strconv"
	"strings"
	"time"
	"unicode"

	"github.com/satori/go.uuid"

	"mutu/misc/conf"
)

func NewUUID() string {
	return strings.Replace(uuid.NewV4().String(), "-", "", -1)
}

func PercentCorrect(total, right int) string {
	if total <= 0 {
		return "0%"
	}
	return fmt.Sprintf("%2.0f%%", float32(right*100)/float32(total))
}

func FormatTime(t time.Time) string {
	return t.Format(conf.TimeFormat)

}

//> 1
// = 0
//< -1
func PercentCompare(a, b string) int {
	x, _ := strconv.Atoi(a[0 : len(a)-1])
	y, _ := strconv.Atoi(b[0 : len(b)-1])
	if x > y {
		return 1
	} else if x == y {
		return 0
	} else {
		return -1
	}
}

func ParseUrl(s string) (url.Values, error) {
	u, err := url.Parse(s)
	if err != nil {
		return nil, err
	}

	m, err := url.ParseQuery(u.RawQuery)
	if err != nil {
		return nil, err
	}

	return m, nil
}

func ConvStringToTime(str string, location *time.Location) (*time.Time, error) {
	length := len(str)
	if length != 10 && length != 19 {
		return nil, errors.New("invalid date time")
	}
	var err error
	y, M, d, h, m, s := 0, 0, 0, 0, 0, 0
	if y, err = strconv.Atoi(str[0:4]); err != nil {
		return nil, err
	}
	if M, err = strconv.Atoi(str[5:7]); err != nil {
		return nil, err
	}
	if d, err = strconv.Atoi(str[8:10]); err != nil {
		return nil, err
	}

	if length == 19 {
		if h, err = strconv.Atoi(str[11:13]); err != nil {
			return nil, err
		}
		if m, err = strconv.Atoi(str[14:16]); err != nil {
			return nil, err
		}
		if s, err = strconv.Atoi(str[17:19]); err != nil {
			return nil, err
		}

	}
	date := time.Date(y, time.Month(M), d, h, m, s, 0, location)
	return &date, nil
}

func RoundFloat(val float64, places int) float64 {
	var t float64
	f := math.Pow10(places)
	x := val * f
	if math.IsInf(x, 0) || math.IsNaN(x) {
		return val
	}
	if x >= 0.0 {
		t = math.Ceil(x)
		if (t - x) > 0.50000000001 {
			t -= 1.0
		}
	} else {
		t = math.Ceil(-x)
		if (t + x) > 0.50000000001 {
			t -= 1.0
		}
		t = -t
	}
	x = t / f

	if !math.IsInf(x, 0) {
		return x
	}

	return t
}

func HaveChineseChar(str string) bool {
	if len(str) == 0 {
		return false
	}

	for _, r := range str {
		if unicode.Is(unicode.Scripts["Han"], r) {
			return true
		}

	}
	return false
}

func StringArrContains(arr []string, str string) bool {
	if arr == nil || len(arr) == 0 {
		return false
	}

	for _, s := range arr {
		if s == str {
			return true
		}
	}
	return false
}

func Md5(str string) string {
	t := md5.New()
	io.WriteString(t, str)
	return fmt.Sprintf("%x", t.Sum(nil))
}
